home *** CD-ROM | disk | FTP | other *** search
/ Clickx 115 / Clickx 115.iso / software / tools / windows / tails-i386-0.16.iso / live / filesystem.squashfs / usr / bin / mid3iconv < prev    next >
Encoding:
Text File  |  2010-06-11  |  4.6 KB  |  140 lines

  1. #!/usr/bin/python
  2. # ID3iconv is a Java based ID3 encoding convertor, here's the Python version.
  3. # Copyright 2006 Emfox Zhou <EmfoxZhou@gmail.com>
  4. #
  5. # This program is free software; you can redistribute it and/or modify
  6. # it under the terms of version 2 of the GNU General Public License as
  7. # published by the Free Software Foundation.
  8. #
  9.  
  10. import os
  11. import sys
  12. import locale
  13.  
  14. from optparse import OptionParser
  15.  
  16. VERSION = (0, 1)
  17.  
  18. def isascii(string):
  19.     return not string or min(string) < '\x127'
  20.  
  21. class ID3OptionParser(OptionParser):
  22.     def __init__(self):
  23.         mutagen_version = ".".join(map(str, mutagen.version))
  24.         my_version = ".".join(map(str, VERSION))
  25.         version = "mid3iconv %s\nUses Mutagen %s" % (
  26.             my_version, mutagen_version)
  27.         return OptionParser.__init__(
  28.             self, version=version,
  29.             usage="%prog [OPTION] [FILE]...",
  30.             description=("Mutagen-based replacement the id3iconv utility, "
  31.                          "which converts ID3 tags from legacy encodings "
  32.                          "to Unicode and stores them using the ID3v2 format."))
  33.  
  34.     def format_help(self, *args, **kwargs):
  35.         text = OptionParser.format_help(self, *args, **kwargs)
  36.         return text + "\nFiles are updated in-place, so use --dry-run first.\n"
  37.  
  38. def update(options, filenames):
  39.     encoding = options.encoding or locale.getpreferredencoding()
  40.     verbose = options.verbose
  41.     noupdate = options.noupdate
  42.     force_v1 = options.force_v1
  43.     remove_v1 = options.remove_v1
  44.  
  45.     def conv(uni):
  46.         return uni.encode('iso-8859-1').decode(encoding)
  47.  
  48.     for filename in filenames:
  49.         if verbose != "quiet":
  50.             print "Updating", filename
  51.  
  52.         if has_id3v1(filename) and not noupdate and force_v1:
  53.             mutagen.id3.delete(filename, False, True)
  54.  
  55.         try: id3 = mutagen.id3.ID3(filename)
  56.         except mutagen.id3.ID3NoHeaderError:
  57.             if verbose != "quiet":
  58.                 print "No ID3 header found; skipping..."
  59.             continue
  60.         except Exception, err:
  61.             if verbose != "quiet":
  62.                 print str(err)
  63.             continue
  64.  
  65.         for tag in filter(lambda t: t.startswith("T"), id3):
  66.             frame = id3[tag]
  67.             if isinstance(frame, mutagen.id3.TimeStampTextFrame):
  68.                 # non-unicode fields
  69.                 continue
  70.             try:
  71.                 text = frame.text
  72.             except AttributeError:
  73.                 continue
  74.             try:
  75.                 text = map(conv, frame.text)
  76.             except (UnicodeError, LookupError):
  77.                 continue
  78.             else:
  79.                 frame.text = text
  80.                 if not text or min(map(isascii, text)):
  81.                     frame.encoding = 3
  82.                 else:
  83.                     frame.encoding = 1
  84.  
  85.         enc = locale.getpreferredencoding()
  86.         if verbose == "debug":
  87.             print id3.pprint().encode(enc, "replace")
  88.  
  89.         if not noupdate:
  90.             if remove_v1: id3.save(filename, v1=False)
  91.             else: id3.save(filename)
  92.  
  93. def has_id3v1(filename):
  94.     f = open(filename, 'rb+')
  95.     try: f.seek(-128, 2)
  96.     except IOError: pass
  97.     else: return (f.read(3) == "TAG")
  98.  
  99. def main(argv):
  100.     parser = ID3OptionParser()
  101.     parser.add_option(
  102.         "-e", "--encoding", metavar="ENCODING", action="store",
  103.         type="string", dest="encoding",
  104.         help=("Specify original tag encoding (default is %s)" %(
  105.         locale.getpreferredencoding())))
  106.     parser.add_option(
  107.         "-p", "--dry-run", action="store_true", dest="noupdate",
  108.         help="Do not actually modify files")
  109.     parser.add_option(
  110.         "--force-v1", action="store_true", dest="force_v1",
  111.         help="Use an ID3v1 tag even if an ID3v2 tag is present")
  112.     parser.add_option(
  113.         "--remove-v1", action="store_true", dest="remove_v1",
  114.         help="Remove v1 tag after processing the files")
  115.     parser.add_option(
  116.         "-q", "--quiet", action="store_const", dest="verbose",
  117.         const="quiet", help="Only output errors")
  118.     parser.add_option(
  119.         "-d", "--debug", action="store_const", dest="verbose",
  120.         const="debug", help="Output updated tags")
  121.  
  122.     for i, arg in enumerate(sys.argv):
  123.         if arg == "-v1": sys.argv[i] = "--force-v1"
  124.         elif arg == "-removev1": sys.argv[i] = "--remove-v1"
  125.  
  126.     (options, args) = parser.parse_args(argv[1:])
  127.  
  128.     if args:
  129.         update(options, args)
  130.     else:
  131.         parser.print_help()
  132.  
  133. if __name__ == "__main__":
  134.     try: import mutagen, mutagen.id3
  135.     except ImportError:
  136.         # Run out of tools/
  137.         sys.path.append(os.path.abspath("../"))
  138.         import mutagen, mutagen.id3
  139.     main(sys.argv)
  140.